package com.zzyl.nursing.service.impl;

import java.io.*;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Arrays;
import java.util.List;

import cn.hutool.core.util.IdcardUtil;
import com.alibaba.fastjson2.JSON;
import com.zzyl.common.ai.AIModelInvoker;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.common.utils.IDCardUtils;
import com.zzyl.nursing.vo.HealthReportVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.HealthAssessmentMapper;
import com.zzyl.nursing.domain.HealthAssessment;
import com.zzyl.nursing.service.IHealthAssessmentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

/**
 * 健康评估Service业务层处理
 * 
 * @author alexis
 * @date 2025-01-06
 */
@Service
public class HealthAssessmentServiceImpl extends ServiceImpl<HealthAssessmentMapper, HealthAssessment> implements IHealthAssessmentService
{
    @Autowired
    private HealthAssessmentMapper healthAssessmentMapper;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private AIModelInvoker aiModelInvoker;

    /**
     * 查询健康评估
     * 
     * @param id 健康评估主键
     * @return 健康评估
     */
    @Override
    public HealthAssessment selectHealthAssessmentById(Long id)
    {
        return healthAssessmentMapper.selectById(id);
    }

    /**
     * 查询健康评估列表
     * 
     * @param healthAssessment 健康评估
     * @return 健康评估
     */
    @Override
    public List<HealthAssessment> selectHealthAssessmentList(HealthAssessment healthAssessment)
    {
        return healthAssessmentMapper.selectHealthAssessmentList(healthAssessment);
    }

    /**
     * 新增健康评估
     * 
     * @param healthAssessment 健康评估
     * @return 结果
     */
    @Override
    public Long insertHealthAssessment(HealthAssessment healthAssessment)
    {
        // 1.设计Prompt提示词（需要从Redis中读取当前身份证号对应的体检报告）
        String prompt = getPrompt(healthAssessment.getIdCard());

        // 2.调用百度千帆大模型，分析体检报告，获取分析结果
        String qianfanResult = aiModelInvoker.qianfanInvoker(prompt);

        // 3.将分析结果保存到数据库中，并返回保存的这条记录的id
        // 将大模型返回的字符串解析为对象，方便取数据
        HealthReportVo healthReportVo = JSON.parseObject(qianfanResult, HealthReportVo.class);

        return saveHealthAssessment(healthReportVo, healthAssessment);
    }

    /**
     * 保存大模型返回的结果和前端传递的老人信息到数据库
     * @param healthReportVo        千帆大模型返回的结果
     * @param healthAssessment      老人基本信息
     * @return  记录的id
     */
    private Long saveHealthAssessment(HealthReportVo healthReportVo, HealthAssessment healthAssessment) {
        // 老人身份证号
        String idCard = healthAssessment.getIdCard();

        healthAssessment.setBirthDate(IDCardUtils.getBirthDateByIdCard(idCard));
        healthAssessment.setAge(IDCardUtils.getAgeByIdCard(idCard));
        healthAssessment.setGender(IDCardUtils.getGenderFromIdCard(idCard));

        // 健康评分
        double healthScore = healthReportVo.getHealthAssessment().getHealthIndex();
        healthAssessment.setHealthScore(String.valueOf(healthScore));

        // 风险等级
        healthAssessment.setRiskLevel(healthReportVo.getHealthAssessment().getRiskLevel());

        // 通过健康评分判断是否建议入住
        healthAssessment.setSuggestionForAdmission(healthScore >= 60 ? 0 : 1);

        // 通过健康评分计算一个推荐的护理等级
        String nursingLevelName = getLevelNameByHealthScore(healthScore);
        healthAssessment.setNursingLevelName(nursingLevelName);

        // 统一先设置未入住
        healthAssessment.setAdmissionStatus(1);

        // 总检日期
        healthAssessment.setTotalCheckDate(healthReportVo.getTotalCheckDate());

        healthAssessment.setAssessmentTime(LocalDateTime.now());

        // 报告总结
        healthAssessment.setReportSummary(healthReportVo.getSummarize());

        // 疾病风险分布
        healthAssessment.setDiseaseRisk(JSON.toJSONString(healthReportVo.getRiskDistribution()));

        // 异常分析
        healthAssessment.setAbnormalAnalysis(JSON.toJSONString(healthReportVo.getAbnormalData()));

        // 八大系统评分
        healthAssessment.setSystemScore(JSON.toJSONString(healthReportVo.getSystemScore()));


        healthAssessmentMapper.insert(healthAssessment);
        return healthAssessment.getId();
    }

    private String getLevelNameByHealthScore(double healthScore) {
        if (healthScore > 100 || healthScore < 0) {
            throw new BaseException("健康评分值不合法");
        }

        if (healthScore >= 90) {
            return "四级护理等级";
        } else if (healthScore >= 80) {
            return "三级护理等级";
        } else if (healthScore >= 70) {
            return "二级护理等级";
        } else if (healthScore >= 60) {
            return "一级护理等级";
        } else {
            return "特级护理等级";
        }
    }

    /**
     * 获取Prompt提示词
     * @param idCard    身份证号
     * @return  提示词
     */
    private String getPrompt(String idCard) {

        try (
                InputStream is = this.getClass().getClassLoader().getResourceAsStream("prompts\\healthReport.txt");
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(isr);
        ) {
            // 1.先从Redis中获取体检报告的内容
            String content = (String) redisTemplate.opsForHash().get(CacheConstants.HEALTH_REPORT, idCard);

            // 优化：读取到Redis中的体检报告后，删除Redis中这个身份证号对应的体检报告
            redisTemplate.opsForHash().delete(CacheConstants.HEALTH_REPORT, idCard);

            // 2.组装提示词
            StringBuilder sb = new StringBuilder();

            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line);
                if (line.contains("体检内容如下：")) {
                    sb.append(content);
                }
            }
            return sb.toString();
        } catch (IOException e) {
            throw new BaseException("读取文件获取提示词失败");
        }
    }

    /**
     * 修改健康评估
     * 
     * @param healthAssessment 健康评估
     * @return 结果
     */
    @Override
    public int updateHealthAssessment(HealthAssessment healthAssessment)
    {
        return healthAssessmentMapper.updateById(healthAssessment);
    }

    /**
     * 批量删除健康评估
     * 
     * @param ids 需要删除的健康评估主键
     * @return 结果
     */
    @Override
    public int deleteHealthAssessmentByIds(Long[] ids)
    {
        return healthAssessmentMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除健康评估信息
     * 
     * @param id 健康评估主键
     * @return 结果
     */
    @Override
    public int deleteHealthAssessmentById(Long id)
    {
        return healthAssessmentMapper.deleteById(id);
    }
}
